package com.tvserials.notification.parser;

import com.tvserials.notification.dto.Episode;
import com.tvserials.notification.dto.EpisodeMedia;
import com.tvserials.notification.dto.Serial;
import com.tvserials.notification.exceptions.NetworkConnectionException;
import com.tvserials.notification.exceptions.PageParseException;
import com.tvserials.notification.utils.VOUtils;
import com.tvserials.notification.vo.*;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by oleksandr.dokienko on 3/25/14.
 */
public class LostFilmHtmlPageParser extends DefaultPageParser {
    public static final String MAIN_LOSTFILM_PAGE = "http://www.lostfilm.tv";
    public static final String HTTP_LOSTFILM_DOWNLOAD = "http://lostfilm.tv/nrdr.php?";
    public static final String LOGIN = "3946138";
    public static final String PASSWORD = "3d5786783e2d30bec79c3e671823fe4a";
    Document document;

    public LostFilmHtmlPageParser() {
    }

    public List<Episode> parseFirstNPages(int pagesCount, List<Serial> allowedSerials) throws NetworkConnectionException, PageParseException {
        List<Episode> listPages = new ArrayList<Episode>();
        for (int i = 1; i <= pagesCount; i++) {
            listPages.addAll(parsePage(new TvEpisodeFilterVO(i, null, allowedSerials)));
        }
        return listPages;
    }

    public List<Serial> parseSerialsList() throws NetworkConnectionException {
        try {
            document = getDocument(MAIN_LOSTFILM_PAGE + "/serials.php");
            Elements contentBody = document.select("div.mid").select("div.bb");

            Elements links = contentBody.select("a[href]");

            ArrayList<Serial> serials = new ArrayList<Serial>();
            for (Element element : links) {
                String ruShowName = element.text();
                ruShowName = ruShowName.substring(0, ruShowName.indexOf("(")).trim();
                String enShowName = element.text();
                enShowName = enShowName.substring(enShowName.indexOf("(") + 1, enShowName.length() - 1);

                Serial serial = new Serial();
                serial.setShowName(ruShowName);
                serial.setSourceType(SourceType.LOST_FILM);
                serials.add(serial);
            }
            return serials;
        } catch (IOException e) {
            throw new NetworkConnectionException(e);
        }
    }

    @Override
    public SourceType getSourceType() {
        return SourceType.LOST_FILM;
    }

    private String getImagePathFromMainPage(String href) {
        try {
            Document doc = Jsoup.connect(href).get();
            Elements img = doc.select("div.mid");
            return MAIN_LOSTFILM_PAGE + img.select("img").attr("src");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected List<Episode> parse(TvEpisodeFilterVO filterVO) throws NetworkConnectionException, PageParseException {
        int pagesNo = filterVO.getPageNo();
        List<Serial> allowedSerials = filterVO.getSerials();
        Date latestSyncDate = filterVO.getLastSyncDate();

        int startWith = (pagesNo - 1) * 15;
        try {
            String CONTENT_PAGE = MAIN_LOSTFILM_PAGE + "/browse.php?o=";
            document = getDocument(CONTENT_PAGE + startWith);
            Elements contentBody = document.select("div.content_body");

            Elements chapterTitles = contentBody.select("span.torrent_title");
            Elements tvShowNames = contentBody.select("span[style]");
            Elements tvShowUrls = contentBody.select("a[href]");
            Elements discussUrls = contentBody.get(0).getElementsByAttributeValueContaining("href", "discuss");
            Elements chapterNumbers = contentBody.select("div[style]");
            Elements dates = contentBody.select("b");
            Elements images = contentBody.select("img[src]");

            List<Episode> tvChapterVOs = new ArrayList<Episode>();
            for (int i = 0; i < 15; i++) {
                String showName = tvShowNames.get(i).text();
                String strDate = dates.get(i * 3 + 1).text();
                Date releaseDate = formatDate(strDate);

                if (isSigned(allowedSerials, showName) && graterThan(latestSyncDate, releaseDate)) {
                    String imageUrl = images.get(i).absUrl("src");
                    String tvShowUrl = MAIN_LOSTFILM_PAGE + tvShowUrls.get(i * 4 + 2).select("a[href]").attr("href");

                    Episode episode = new Episode();
                    episode.setShowName(new Serial(showName, SourceType.LOST_FILM));
                    episode.setChapterName(chapterTitles.get(i).child(0).text());
                    episode.setChapterNumber(chapterNumbers.get(i).text());
                    episode.setReleaseDate(releaseDate);
                    episode.setImage(VOUtils.loadImage(imageUrl));
                    episode.setChapterDetailsUrl(tvShowUrl);
                    episode.setDiscussUrl(MAIN_LOSTFILM_PAGE + discussUrls.get(i).attr("href"));

                    List<EpisodeMedia> episodeMedias = readMediaData(episode);
                    episode.setMediaQualities(episodeMedias);

                    tvChapterVOs.add(episode);
                }
            }
            return tvChapterVOs;
        } catch (IOException e) {
            throw new NetworkConnectionException(e);
        } catch (ParseException e) {
            throw new PageParseException(e);
        } catch (NullPointerException e) {
            throw new PageParseException(e);
        }
    }

    private boolean isSigned(List<Serial> allowedSerials, String showName) {
        return allowedSerials.contains(new Serial(showName, getSourceType()));
    }

    public List<EpisodeMedia> readMediaData(Episode episodeVO) throws NetworkConnectionException {
        try {
            String att = episodeVO.getAttributes().replace("cat", "c");
            Connection connection = Jsoup.connect(HTTP_LOSTFILM_DOWNLOAD + att).followRedirects(true);
            connection.cookie("uid", LOGIN);
            connection.cookie("pass", PASSWORD);

            Document document = connection.get();
            Elements elements = document.select("body > div:nth-child(2) > div:nth-child(6)").get(0).children();

            List<EpisodeMedia> episodeMedias = new ArrayList<EpisodeMedia>();
            for (Element item : elements) {
                Element urlNode = item.select("a[href]").get(0);
                String url = urlNode.attr("href");
                String size = item.getElementsContainingOwnText("Размер").get(0).childNode(0).toString();
                String title = urlNode.text();

                EpisodeMedia episodesRssVO = new EpisodeMedia();
                episodesRssVO.setLink(url);
                episodesRssVO.setTitle(title);
                episodesRssVO.setSize(prepareSizeTitle(size));
                episodeMedias.add(episodesRssVO);
            }

            return episodeMedias;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    private String prepareSizeTitle(String text) {
        String size = text.replace("Видео:", "").replace("Размер:", "");
        return size;
    }


    private Document getDocument(String page) throws IOException {
        Connection connection = Jsoup.connect(page);
        connection.userAgent("Mozilla");
        connection.timeout(PageParserFactory.TIMEOUT);
        return connection.get();
    }

    private Date formatDate(String str) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy hh:mm");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT-4"));
        return simpleDateFormat.parse(str);
    }


}
